package pvt.delez.pam;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.common.util.EList;

public class PAM {

	private Map<String, Project> projects = new HashMap<String, Project>();
	private Collection<Project> allProjects;
	
	private Map<Object, Set<Relationship>> reverseConnections = new HashMap<Object, Set<Relationship>>();
	private Map<Project, Set<Relationship>> connections = new HashMap<Project, Set<Relationship>>();

	private static ThreadLocal<PAM> projectHolder = new ThreadLocal<PAM>();

	private PAM() {
	}

	public static PAM setProjects(Collection<Project> projects,
			Collection<Project> allProjects) {
		PAM pam = new PAM();
		for (Project project : projects) {
			pam.projects.put(project.getName(), project);
		}
		pam.buildDuplexingConnection(allProjects);
		pam.allProjects = allProjects;
		projectHolder.set(pam);
		return pam;
	}

	public static Collection<Project> getAllProjectSet() {
		PAM pam = projectHolder.get();
		return pam == null ? Collections.EMPTY_SET : pam.allProjects;
	}

	private void buildDuplexingConnection(Collection<Project> allProjects) {
		for (Project p : allProjects) {
			EList<Library> libs = p.getLibraries();
			Set<Relationship> relation = connections.get(p);
			if(relation == null)
			{
				relation = new HashSet<Relationship>();
				connections.put(p, relation);
			}
			/*
			for (Library library : libs) {
				Set<Relationship> reverseRelation = reverseConnections.get(library);
				if(reverseRelation == null)
				{
					reverseRelation = new HashSet<Relationship>();
					reverseConnections.put(library, reverseRelation);
				}
				Relationship r = new Relationship(p, library);
				reverseRelation.add(r);
				relation.add(r);
			}*/
			EList<Project> projects = p.getDepends();
			for (Project dep : projects) {
//				ret.add(new Relationship(p, dep));
				Set<Relationship> reverseRelation = reverseConnections.get(dep);
				if(reverseRelation == null)
				{
					reverseRelation = new HashSet<Relationship>();
					reverseConnections.put(dep, reverseRelation);
				}
				Relationship r = new Relationship(p, dep);
				reverseRelation.add(r);
				relation.add(r);
			}
		}

	}

	public static Collection<Relationship> getReverseConnections(Object key) {
		PAM pam = projectHolder.get();
		return pam == null ? Collections.EMPTY_SET : pam.reverseConnections.get(key);
	}
	public static Collection<Relationship> getConnections(Object key) {
		PAM pam = projectHolder.get();
		return pam == null ? Collections.EMPTY_SET : pam.connections.get(key);
	}

	public static Collection<Project> getProjects() {
		PAM pam = projectHolder.get();
		return pam == null ? Collections.EMPTY_SET : pam.projects.values();
	}
	
	public static PAM addProject(Project project) {
		PAM pam = projectHolder.get();
		if (pam == null) {
			pam = new PAM();
			projectHolder.set(pam);
		}
		pam.projects.put(project.getName(), project);
		return pam;
	}

	public static Project findProject(String name) {
		PAM pam = projectHolder.get();
		return pam == null ? null : pam.projects.get(name);
	}

}
